home *** CD-ROM | disk | FTP | other *** search
/ Developer CD Series 1998 August: Tool Chest / Dev.CD Aug 98 TC.toast / Tool Chest / Testing & Debugging / Virtual User / Virtual User Current Release / Examples / External Tool Templates / CPlus Tool Template / Application.cp < prev    next >
Encoding:
Text File  |  1998-06-04  |  22.0 KB  |  860 lines  |  [TEXT/MPS ]

  1. /*
  2.  *    File:        Application.cp
  3.  *
  4.  *    Contains:    xxx put contents here xxx
  5.  *
  6.  *    Written by:    Rick Violet
  7.  *
  8.  *    Copyright:    © 1992 by Apple Computer, Inc., all rights reserved.
  9.  *
  10.  *    Change History (most recent first):
  11.  *
  12.  *                10/16/94    SBR        Threaded App and RequestDispatcher
  13.  *                11/18/92    RV        xxx put comment here xxx
  14.  *
  15.  *    To Do:
  16.  */
  17.  
  18. // Mac Includes
  19. #include <QuickDraw.h>
  20. #include <Fonts.h>
  21. #include <Controls.h>
  22. #include <Windows.h>
  23. #include <Menus.h>
  24. #include <TextEdit.h>
  25. #include <Dialogs.h>
  26. #include <ToolUtils.h>
  27. #include <Memory.h>
  28. #include <SegLoad.h>
  29. #include <Traps.h>
  30. #include <GestaltEqu.h>
  31. #include <EPPC.h>
  32. #include <CursorCtl.h>
  33. #include "new.h"
  34.  
  35. #ifndef        __Application__
  36. #include        "Application.h"
  37. #endif
  38.  
  39. #ifndef        __RequestDispatcher__
  40. #include        "RequestDispatcher.h"
  41. #endif
  42.  
  43. #ifndef        __AERequest__
  44. #include        "AERequest.h"
  45. #endif
  46.  
  47. #ifndef     __Configuration__
  48. #include        "Configuration.h"
  49. #endif
  50.  
  51. //—————————————————————————————————————————————————————————————————————————————————————
  52. //    CONSTANTS
  53. //—————————————————————————————————————————————————————————————————————————————————————
  54. // Size of Application Heap space and Stack space needed
  55. const long kHeapSpaceNeeded     = (100 * 1024);    // Heap Space in bytes
  56. const long kStackSpaceNeeded     = (100 * 1024);    // Stack Space in bytes
  57.  
  58. //—————————————————————————————————————————————————————————————————————————————————————
  59. // Constants to use when being Multi-Finder aware
  60. const short kOsEvent                 = app4Evt;    // event used by MultiFinder
  61. const short kSuspendResumeMessage     = 0x01;        // high byte of suspend/resume event message
  62. const short kClipConvertMask         = 0x02;        // bit of message field clip conversion
  63. const short kResumeMask             = 0x01;        // bit of message field for resume vs. suspend
  64. const short kMouseMovedMessage         = 0xFA;        // high byte of mouse-moved event message
  65.  
  66. //—————————————————————————————————————————————————————————————————————————————————————
  67. #ifndef        THINK_CPLUS
  68.     #ifndef    __MWERKS__
  69.         extern "C" 
  70.         { 
  71.             // from MPW standard library
  72.             void _DataInit(void);                // sets up A5 globals
  73.         };
  74.     #endif
  75. #endif
  76.  
  77. //—————————————————————————————————————————————————————————————————————————————————————
  78. //                                Global Variables
  79. //—————————————————————————————————————————————————————————————————————————————————————
  80.         Application*            gTheApplication;
  81. extern    RequestDispatcher*        gTheRequestDispatcher;
  82.  
  83.         Configuration            gConfiguration;
  84.         Ptr                     gStrippedAddress = NULL;
  85.  
  86.         /*SBR Hacked this in 10/16/94 */
  87.         ThreadID                gRequestDispatcherThreadID = kNoThreadID;
  88.         long                    gRDThreadReturnValue;
  89.  
  90. //—————————————————————————————————————————————————————————————————————————————————————
  91. //    main - the main entry point
  92. //—————————————————————————————————————————————————————————————————————————————————————
  93. int 
  94. main(void)
  95. {
  96.     gTheApplication = new Application() ;
  97.     if( gTheApplication )
  98.     {
  99.         gTheApplication->Run();
  100.         delete gTheApplication;
  101.     }
  102.     
  103.     return 0;
  104. }
  105.  
  106. //—————————————————————————————————————————————————————————————————————————————————————
  107. //    AEOpenHandler - handles 'aevt' 'oapp' apple event
  108. //—————————————————————————————————————————————————————————————————————————————————————
  109. pascal    OSErr  
  110. AEOpenHandler (AppleEvent*, AppleEvent*, long )
  111. {
  112.     //    Standard (empty) handler for the 'oapp' Apple Event. Our program does
  113.     //    not need anything special here, so "noErr" can simply be returned.
  114.  
  115.     return(noErr);
  116. }
  117.  
  118.  
  119. //—————————————————————————————————————————————————————————————————————————————————————
  120. //    AEOpenDocHandler - handles 'aevt' 'odoc' apple event
  121. //—————————————————————————————————————————————————————————————————————————————————————
  122. pascal    OSErr 
  123. AEOpenDocHandler (AppleEvent*, AppleEvent*, long )
  124. {
  125.     //    Standard (empty) handler for the 'odoc' Apple Event. Our program does
  126.     //    not have documents, so we ignore this Apple Event.
  127.  
  128.     return(noErr);
  129. }
  130.  
  131. //—————————————————————————————————————————————————————————————————————————————————————
  132. //    AEPrintHandler - handles 'aevt' 'pdoc' apple event
  133. //—————————————————————————————————————————————————————————————————————————————————————
  134. pascal    OSErr  
  135. AEPrintHandler (AppleEvent*, AppleEvent*, long )
  136. {
  137.     //    Standard (empty) handler for the 'pdoc' Apple Event. Our program does
  138.     //    not have documents, so we ignore this Apple Event.
  139.  
  140.     return(noErr);
  141. }
  142.  
  143. //—————————————————————————————————————————————————————————————————————————————————————
  144. //    AEQuitHandler - handles 'aevt' 'quit' apple event
  145. //—————————————————————————————————————————————————————————————————————————————————————
  146. pascal    OSErr  
  147. AEQuitHandler (AppleEvent*, AppleEvent*, long )
  148. {
  149.     //    Standard handler for the 'quit' Apple Event. You must never, ever call
  150.     //    ExitToShell from within an Apple Event handler. It is certain death
  151.     //    for your application. Thus, we just set a flag which is examined later
  152.     //    in the main event loop.
  153.  
  154.     gTheApplication->DoMenuCommand( kFileMenuID, kQuitItem );
  155.     return(noErr);
  156. }
  157.  
  158. //—————————————————————————————————————————————————————————————————————————————————————
  159. //                                Application Object
  160. //—————————————————————————————————————————————————————————————————————————————————————
  161.  
  162. //—————————————————————————————————————————————————————————————————————————————————————
  163. //    Application::Application - constructor
  164. //—————————————————————————————————————————————————————————————————————————————————————
  165. Application::Application(void)
  166. {
  167.         //————    First things first
  168.     InitializeToolBox();
  169.     GetThisProcessInfo();
  170.  
  171.         //————    initialize our class variables
  172.     fDone = false;
  173.     fInBackground = false;
  174.     fWhichWindow = nil;
  175.     fMessagePtrOrig = nil;
  176.     fReplyPtrOrig = nil;
  177.     fSleepTicks = 1;
  178.     
  179.         //————    Install Handlers for oapp, odoc, pdoc, quit
  180.         //————    the 4 required Apple events
  181.     if( InstallRequiredAEHandlers() != noErr )
  182.         TerminalError( kAppErrStrings, kAppInitFail );
  183.  
  184.         //————    Install Handler for 'v.u.' Apple events
  185.     if( AERequest::InstallAppleEventHandler() != noErr )
  186.         TerminalError( kAppErrStrings, kAppInitFail );
  187.  
  188.         //————    construct the RequestDispatcher object
  189.         //————    create a new thread for it if application is threaded
  190.     CreateRequestDispatcher();
  191. }
  192.  
  193. //—————————————————————————————————————————————————————————————————————————————————————
  194. //    Application::~Application - destructor
  195. //—————————————————————————————————————————————————————————————————————————————————————
  196. Application::~Application(void)
  197. {
  198.     if( gTheRequestDispatcher )
  199.     {
  200.         if( fIsThreaded )
  201.             DisposeThread( gRequestDispatcherThreadID, &gRDThreadReturnValue, false );
  202.         
  203.         delete gTheRequestDispatcher;
  204.     }
  205. }
  206.  
  207. //—————————————————————————————————————————————————————————————————————————————————————
  208. //    Application::InstallRequiredAEHandlers
  209. //—————————————————————————————————————————————————————————————————————————————————————
  210. OSErr 
  211. Application::InstallRequiredAEHandlers(void)
  212. {
  213.     OSErr    tErr;
  214.  
  215.     //————    Setup the AppleEvent Handlers
  216.         //————    Setup 'oapp' handler
  217.     tErr = AEInstallEventHandler(kCoreEventClass,
  218.                                    kAEOpenApplication,
  219.                                    NewAEEventHandlerProc(AEOpenHandler),
  220.                                    0, false);
  221.     if (tErr != noErr) 
  222.         return tErr;
  223.     
  224.         //————    Setup 'odoc' handler
  225.     tErr = AEInstallEventHandler(kCoreEventClass,
  226.                                    kAEOpenDocuments,
  227.                                    NewAEEventHandlerProc(AEOpenDocHandler),
  228.                                    0, false);
  229.     if (tErr != noErr) 
  230.         return tErr;
  231.     
  232.         //————    Setup 'pdoc' handler
  233.     tErr = AEInstallEventHandler(kCoreEventClass,
  234.                                    kAEPrintDocuments,
  235.                                    NewAEEventHandlerProc(AEPrintHandler),
  236.                                    0, false);
  237.     if (tErr != noErr)
  238.         return tErr;
  239.  
  240.         //————    Setup 'quit' handler
  241.     tErr = AEInstallEventHandler(kCoreEventClass,
  242.                                    kAEQuitApplication,
  243.                                    NewAEEventHandlerProc(AEQuitHandler),
  244.                                    0, false);
  245.     if (tErr != noErr) 
  246.         return tErr;
  247.     
  248.     return noErr;
  249. }
  250.  
  251. //—————————————————————————————————————————————————————————————————————————————————————
  252. //    Application::SleepVal
  253. //—————————————————————————————————————————————————————————————————————————————————————
  254. unsigned long 
  255. Application::SleepVal(void)
  256. {
  257.     if ( !fInBackground )
  258.     {
  259.         return GetCaretTime();
  260.     }
  261.     else
  262.     {
  263.         return fSleepTicks;
  264.     }
  265. }
  266.  
  267. //—————————————————————————————————————————————————————————————————————————————————————
  268. //    Application::Run
  269. //—————————————————————————————————————————————————————————————————————————————————————
  270. void 
  271. Application::Run(void)
  272. {
  273.     while( !fDone )
  274.     {
  275.         DoEvent();
  276.  
  277.             /*SBR Hacked this in 10/16/94 */
  278.         if( fIsThreaded )
  279.         {
  280.                 //————    In case a non-threaded service was queued, suggest this thread
  281.                 //————    to ensure threaded service do not get any time.
  282.                 //————    The application *always* yields to the RequestDispatcher.
  283.             YieldToThread( gRequestDispatcherThreadID );
  284.         }
  285.         else
  286.         {
  287.             gTheRequestDispatcher->DoRequests();
  288.         }
  289.     }
  290.  
  291.         //————    Clean up, cancel requests, etc.
  292.     ExitLoop();
  293. }
  294.  
  295. //—————————————————————————————————————————————————————————————————————————————————————
  296. //    Application::ExitLoop
  297. //—————————————————————————————————————————————————————————————————————————————————————
  298. void 
  299. Application::ExitLoop(void)
  300. {
  301.         /*SBR Hacked this out 10/16/94 */
  302.     //gTheRequestDispatcher->CancelCurrentRequest()
  303.  
  304.         /*SBR Hacked this in 10/16/94 */
  305.     if( fIsThreaded )
  306.     {
  307.         while( !gTheRequestDispatcher->CancelAllRequests() )
  308.         {
  309.             YieldToAnyThread();
  310.             SystemTask();
  311.         }
  312.     }
  313.     else
  314.     {
  315.             //————    If application is not threaded, the only thing to do 
  316.             //————    is cancel all and return, since returning is only way 
  317.             //————    to give time to the request we want to cancel.
  318.         gTheRequestDispatcher->CancelAllRequests();
  319.         return ;
  320.     }
  321. }
  322.  
  323. //—————————————————————————————————————————————————————————————————————————————————————
  324. //    Application::DoEvent
  325. //—————————————————————————————————————————————————————————————————————————————————————
  326. Boolean 
  327. Application::DoEvent( unsigned long pSleepTicks, short pEventMask )
  328. {
  329.     Boolean     tHaveEvnt;
  330.     EventRecord    tEvent;
  331.     
  332.     if( pSleepTicks == 0 )
  333.     {
  334.         pSleepTicks = SleepVal();
  335.     }
  336.  
  337.         //————    Get the next event from the Event Queue
  338.     tHaveEvnt = WaitNextEvent( pEventMask, &tEvent, pSleepTicks, nil );
  339.     fTheEvent = tEvent;
  340.     
  341.     if ( tHaveEvnt )
  342.     {
  343.         switch (fTheEvent.what)
  344.         {
  345.                 //————    mouseDown
  346.             case mouseDown:
  347.             {
  348.                 DoMouseDown();
  349.             }
  350.             break;
  351.             
  352.                 //————    Key Down Event
  353.             case keyDown:
  354.             case autoKey:
  355.             {
  356.                 DoKeyDown();
  357.             }
  358.             break;
  359.             
  360.                 //————    OSEvent
  361.             case kOsEvent:
  362.             {
  363.                 DoOSEvent();
  364.             }
  365.             break;
  366.     
  367.                 //————    High Level Event
  368.             case kHighLevelEvent:
  369.             {
  370.                 DoHighLevelEvent();
  371.             }
  372.             break;
  373.     
  374.                 //————    all others
  375.             default:
  376.             {
  377.             }
  378.             break;
  379.         } 
  380.     }
  381.     return tHaveEvnt;
  382. }
  383.  
  384. //—————————————————————————————————————————————————————————————————————————————————————
  385. //    Application::DoMouseDown
  386. //—————————————————————————————————————————————————————————————————————————————————————
  387. void 
  388. Application::DoMouseDown()
  389. {
  390.     long        tMenuSelectResult;
  391.     short        tPartCode;
  392.     WindowPtr    tWind;
  393.     EventRecord    tEvent;
  394.  
  395.         //————    Determine which window
  396.     tPartCode = FindWindow( fTheEvent.where, &tWind );
  397.     
  398.         //————    Save this fact
  399.     fWhichWindow = tWind;
  400.  
  401.         //————    Get a copy of the event
  402.     tEvent = fTheEvent;
  403.     
  404.     switch( tPartCode )
  405.     {
  406.         case inSysWindow:
  407.         {
  408.             DoMouseInSysWindow();
  409.         }
  410.         break;
  411.         
  412.         case inDrag:
  413.         {
  414.             DragWindow(tWind, fTheEvent.where, &qd.screenBits.bounds);
  415.         }
  416.         break;
  417.         
  418.         case inMenuBar:
  419.         {
  420.             tMenuSelectResult = MenuSelect( tEvent.where );
  421.             if( tMenuSelectResult != 0 )
  422.             {
  423.                 DoMenuCommand( HiWord( tMenuSelectResult ), LoWord( tMenuSelectResult ) );
  424.             }
  425.         }
  426.         break;
  427.     }
  428. }
  429.  
  430. //—————————————————————————————————————————————————————————————————————————————————————
  431. //    Application::DoKeyDown
  432. //—————————————————————————————————————————————————————————————————————————————————————
  433. void 
  434. Application::DoKeyDown()
  435. {
  436.     char tKey;
  437.     long tMenuKeyResult;
  438.  
  439.     tKey = (char) (fTheEvent.message & charCodeMask);
  440.     
  441.         //————    if its a Request key
  442.         //————    and not a auto-key
  443.     if( (fTheEvent.modifiers & cmdKey) && (fTheEvent.what == keyDown) )
  444.     {
  445.         tMenuKeyResult = MenuKey( tKey );
  446.         if( tMenuKeyResult != 0 )
  447.         {
  448.                 //————    Do Request key menu selection
  449.             DoMenuCommand( HiWord( tMenuKeyResult ), LoWord( tMenuKeyResult ) );
  450.         }
  451.         else
  452.         {
  453.                 //————    Do ordinary key stroke
  454.         }
  455.     }
  456. }
  457.  
  458. //—————————————————————————————————————————————————————————————————————————————————————
  459. //    Application::DoOSEvent
  460. //—————————————————————————————————————————————————————————————————————————————————————
  461. void 
  462. Application::DoOSEvent(void)
  463. {
  464.     unsigned char tEventType;
  465.  
  466.         //————    is it a multifinder event?
  467.         //————    high byte of message is type of event
  468.     tEventType = (unsigned char) (fTheEvent.message >> 24) & 0x00ff;
  469.     switch ( tEventType ) 
  470.     {     
  471.         case kMouseMovedMessage:
  472.         {
  473.         }
  474.         break;
  475.  
  476.         case kSuspendResumeMessage:
  477.         {
  478.             fInBackground = !fInBackground;
  479.             if( !fInBackground )
  480.             {
  481.                 InitCursor();
  482.             }
  483.         }
  484.         break;
  485.  
  486.         default:
  487.         {
  488.         }
  489.         break;
  490.     }
  491. }
  492.  
  493. //—————————————————————————————————————————————————————————————————————————————————————
  494. //    Application::DoHighLevelEvent
  495. //—————————————————————————————————————————————————————————————————————————————————————
  496. void 
  497. Application::DoHighLevelEvent()
  498. {
  499.     OSErr            tErr;
  500.     
  501.     tErr = AEProcessAppleEvent( &fTheEvent );
  502.  
  503.         //————    see AERequest.cp and Request.cp for details
  504.     FixAEManagerBugPart2();
  505. }
  506.  
  507. //—————————————————————————————————————————————————————————————————————————————————————
  508. //    Application::DoMenuCommand
  509. //—————————————————————————————————————————————————————————————————————————————————————
  510. void 
  511. Application::DoMenuCommand( short tMenuID, short tMenuItem )
  512. {
  513.     short        tItemHit;
  514.     Str255        tDAName;
  515.     short        tDARefNum;
  516.  
  517.     switch ( tMenuID )
  518.     {
  519.             //————    Apple Menu
  520.         case kAppleMenuID:
  521.         {
  522.             switch ( tMenuItem )
  523.               {
  524.                     //————    About
  525.                 case kAboutItem:
  526.                 {
  527.                     tItemHit = Alert( kAboutAlertID, nil );
  528.                 }
  529.                 break;
  530.                 
  531.                     //————    Desk Accessory
  532.                 default:
  533.                 {
  534.                     GetItem( GetMHandle( kAppleMenuID ), tMenuItem, tDAName );
  535.                     tDARefNum = OpenDeskAcc( tDAName );
  536.                 }
  537.                 break;
  538.             }
  539.         }
  540.         break;
  541.             
  542.             //————    File Menu
  543.         case kFileMenuID:
  544.         {
  545.             switch ( tMenuItem )
  546.             {
  547.                     //————    Quit
  548.                 case kQuitItem:
  549.                 {
  550.                     Terminate();
  551.                 }
  552.                 break;
  553.             }
  554.             break;
  555.         }
  556.     }
  557.       
  558.         //———— unhighlight what MenuSelect (or MenuKey) hilited 
  559.     HiliteMenu(0);    
  560.  
  561. //—————————————————————————————————————————————————————————————————————————————————————
  562. //    Application::Terminate
  563. //—————————————————————————————————————————————————————————————————————————————————————
  564. void 
  565. Application::Terminate(void)
  566. {
  567.     fDone = true;
  568. }
  569.  
  570. //—————————————————————————————————————————————————————————————————————————————————————
  571. //    Application::InitializeToolBox
  572. //—————————————————————————————————————————————————————————————————————————————————————
  573. void    
  574. Application::InitializeToolBox(void)
  575. {
  576.     OSErr            tErr;
  577.     long            heapSize;
  578.  
  579.         /*SBR Hacked this in from Application::Application() 10/16/94 */
  580.     Handle        tMenuBarHandle;
  581.     MenuHandle    tAppleMenu;
  582.  
  583.         //————    initialize Mac Toolbox components
  584.     InitGraf((Ptr) &qd.thePort);
  585.     InitFonts();
  586.     InitWindows();
  587.     InitMenus();
  588.     TEInit();
  589.     InitDialogs(0);
  590.     InitCursor();
  591.  
  592.         //————    Unload data segment: note that _DataInit must not be in Main!
  593.         //————    Ignore if using Think C++ or MetroWerks
  594.     #ifndef        THINK_CPLUS
  595.         #ifndef    __MWERKS__
  596.             UnloadSeg( (ProcPtr) _DataInit );
  597.         #endif
  598.     #endif
  599.  
  600.         //————    Build the menu bar before displaying any dialogs
  601.         //————    This shows which application displayed the dialog
  602.     tMenuBarHandle = GetNewMBar( kMenuBarID );
  603.     if( tMenuBarHandle )
  604.     {
  605.         SetMenuBar( tMenuBarHandle );
  606.         DisposHandle( tMenuBarHandle );
  607.     }
  608.         //————    add Apple Menu Items
  609.     tAppleMenu = GetMHandle( kAppleMenuID );
  610.     if( tAppleMenu )
  611.     {
  612.         AddResMenu( tAppleMenu, 'DRVR' );
  613.     }
  614.     DrawMenuBar();
  615.  
  616.         //————    set the global gConfiguration
  617.     DefineConfiguration( gConfiguration );
  618.  
  619.         //———— Are we running on a 128K ROM machine or better?
  620.     if ( !gConfiguration.hasROM128K )
  621.     {
  622.         TerminalError( kAppErrStrings, kWrongMachineErr );
  623.     }
  624.  
  625.         /*SBR Hacked this 10/16/94 */
  626.         //————    Are we running on a platform with the Process Manager?
  627.         //————    (this implies System 7.0 or later)
  628.     if ( !gConfiguration.hasProcessMgr )
  629.     {
  630.         TerminalError( kAppErrStrings, kWrongSysSWVers );
  631.     }
  632.     else
  633.  
  634.         //————    if we need more stack space, get it now
  635.     if ( kStackSpaceNeeded > StackSpace())
  636.     {
  637.             //————    new address is heap size + current stack - needed stack
  638.         SetApplLimit((Ptr) ((long) GetApplLimit() - kStackSpaceNeeded + StackSpace()));
  639.         tErr = MemError();
  640.         if( tErr != noErr )
  641.         {
  642.             TerminalError( kAppErrStrings, kSmallSizeErr );        
  643.         }
  644.     }
  645.         //————    Check for minimum heap size
  646.     heapSize = (long)GetApplLimit() - (long)ApplicZone();
  647.     if( heapSize < kHeapSpaceNeeded )
  648.     {
  649.         TerminalError( kAppErrStrings, kSmallSizeErr );
  650.     }
  651.         //————    expand the heap so new code segments load at the top
  652.         //————    MaxApplZone() must be called before creating any new threads
  653.     MaxApplZone();
  654.     
  655.  
  656.         //————    SBR 10/16/94 Hacked this in from RequestDispatcher::RequestDispatcher()
  657.         //————    Make sure that AppleEvents are available, in the right version
  658.     if( !gConfiguration.hasAppleEventMgr101 )
  659.     {
  660.         TerminalError( kAppErrStrings, kAppleEventVersionErr );
  661.     }
  662.  
  663.         //————    Check if there are any threads at all
  664.     if( gConfiguration.hasThreadMgr )
  665.     {
  666.         fIsThreaded = true;
  667.     }
  668.     else
  669.     {
  670.             //————    To allow non-threaded operation, do not terminate here
  671.         //    TerminalError( kAppErrStrings, kThreadVersionErr );
  672.  
  673.         fIsThreaded = false;
  674.         DebugStr( "\pApplication::InitializeToolBox- fIsThreaded = false. Type cmd-g to continue." );
  675.     }
  676.  
  677.         //————    Setup for spinning cursor
  678.         //————    Ignore if using Think C++ or MetroWerks
  679.     #ifndef        THINK_CPLUS
  680.         #ifndef    __MWERKS__
  681.             InitCursorCtl( nil );
  682.         #endif
  683.     #endif
  684. }
  685.  
  686. //—————————————————————————————————————————————————————————————————————————————————————
  687. //    Application::GetThisProcessInfo
  688. //—————————————————————————————————————————————————————————————————————————————————————
  689. void 
  690. Application::GetThisProcessInfo()
  691. {
  692.     fProcessInfo.processNumber.highLongOfPSN = 0;
  693.     fProcessInfo.processNumber.lowLongOfPSN = kCurrentProcess;
  694.     
  695.     fProcessInfo.processInfoLength = sizeof(ProcessInfoRec);
  696.     fProcessInfo.processName = (StringPtr)&fProcessName;
  697.     fProcessInfo.processAppSpec = NULL;
  698.  
  699.     if( GetProcessInformation(&fProcessInfo.processNumber, &fProcessInfo) == noErr )
  700.     {
  701.         ProcessSerialNumber tCurrPSN, tFrontPSN;
  702.         
  703.         GetCurrentProcess( &tCurrPSN );
  704.         GetFrontProcess( &tFrontPSN );
  705.         
  706.         SameProcess( &tCurrPSN, &tFrontPSN, &fInBackground );
  707.         fInBackground = !fInBackground;
  708.     }
  709.     else
  710.     {
  711.         fInBackground = true;
  712.     }
  713. }
  714.  
  715. //—————————————————————————————————————————————————————————————————————————————————————
  716. //    Application::TrapAvailable
  717. //—————————————————————————————————————————————————————————————————————————————————————
  718. Boolean 
  719. Application::TrapAvailable(short tNumber,TrapType tType)
  720. {
  721.     // Check and see if the trap exists. On 64K ROM machines, tType will be ignored.
  722.     return NGetTrapAddress(tNumber, tType) != NGetTrapAddress(_Unimplemented, OSTrap);
  723. }
  724.  
  725. //—————————————————————————————————————————————————————————————————————————————————————
  726. //    Application::SpinTheCursor
  727. //—————————————————————————————————————————————————————————————————————————————————————
  728. void 
  729. Application::SpinTheCursor()
  730. {
  731.     #ifndef        THINK_CPLUS
  732.         #ifndef    __MWERKS__
  733.             SpinCursor( 0 );
  734.         #endif
  735.     #endif
  736.  
  737.     DoEvent( 10, everyEvent );
  738. }
  739.  
  740. //—————————————————————————————————————————————————————————————————————————————————————
  741. //    TerminalError
  742. //—————————————————————————————————————————————————————————————————————————————————————
  743. void 
  744. TerminalError( short errResID, short errCode )
  745. {
  746.     Str255 message;
  747.  
  748.     SetCursor(&qd.arrow);
  749.     GetIndString(message, errResID, errCode);
  750.     ParamText(message, "\p", "\p", "\p");
  751.     Alert(kUserAlertID, /*(ModalFilterProcPtr)*/ nil);
  752.  
  753.     delete gTheApplication;
  754.     
  755.     ExitToShell();
  756. }
  757.  
  758.  
  759. //—————————————————————————————————————————————————————————————————————————————————————
  760. //    Application::SetSleepTicks()
  761. //—————————————————————————————————————————————————————————————————————————————————————
  762. long 
  763. Application::SetSleepTicks( long pSleepTicks )
  764. {
  765.     long prevTicks = fSleepTicks;
  766.     fSleepTicks = pSleepTicks;
  767.     return prevTicks;
  768. }
  769.  
  770.  
  771.         /*SBR Hacked this in 10/16/94 */
  772. //—————————————————————————————————————————————————————————————————————————————————————
  773. //    Application::CreateRequestDispatcher()
  774. //—————————————————————————————————————————————————————————————————————————————————————
  775. void 
  776. Application::CreateRequestDispatcher()
  777. {
  778.     OSErr         theErr;
  779.  
  780.         //————    construct the RequestDispatcher object
  781.     gTheRequestDispatcher = new RequestDispatcher();
  782.     if( gTheRequestDispatcher == nil )
  783.     {
  784.         TerminalError( kDispatcherErrStrings, kDispatcherConstructErr );
  785.     }
  786.         //————    initialize beachball position
  787.     fCursorTicks = 0;
  788.  
  789.         //————    if there are no threads, we are done
  790.     if( !fIsThreaded )
  791.         return;
  792.     
  793.         //————    create the RequestDispatcher thread
  794.     theErr = NewThread(    kCooperativeThread, 
  795.                         (ThreadEntryProcPtr)&RequestDispatcherThread, 0, 0,
  796.                         kNewSuspend + kCreateIfNeeded + kFPUNotNeeded, 0,
  797.                         &gRequestDispatcherThreadID );
  798.     
  799.     if( theErr != noErr )
  800.     {
  801.         DebugStr("\pDid not create gRequestDispatcherThreadID");
  802.     }
  803.     
  804.     theErr = SetThreadState( gRequestDispatcherThreadID, kReadyThreadState, kNoThreadID );
  805.                         
  806.     if( theErr != noErr )
  807.     {
  808.         DebugStr( "\pError setting gRequestDispatcherThreadID to kReadyThreadState" );
  809.     }
  810. }
  811.  
  812.  
  813. //—————————————————————————————————————————————————————————————————————————————————————
  814. //    RequestDispatcherThread
  815. //—————————————————————————————————————————————————————————————————————————————————————
  816. void* 
  817. RequestDispatcherThread( void *threadParam )
  818. {
  819.     if (threadParam)    ;
  820.     
  821.         //———— based on RequestDispatcher::DoOneRequest()
  822.     gTheRequestDispatcher->DoRequests();
  823.  
  824.     return nil;
  825. }
  826.  
  827.  
  828.  
  829. //—————————————————————————————————————————————————————————————————————————————————————
  830. //    Application::FixAEManagerBugPart2    - delete the Apple Event and its result to fix a bug.
  831. //—————————————————————————————————————————————————————————————————————————————————————
  832. void
  833. Application::FixAEManagerBugPart2()
  834. {
  835.     OSErr        tErr = noErr;
  836.     
  837.         //————    Skip if pointers are nil, i.e. FixAEManagerBugPart1() was not executed 
  838.     if( fMessagePtrOrig == nil )
  839.         return;
  840.     
  841.         //————    Delete the original message AppleEvent Record
  842.     tErr =  AEDisposeDesc( fMessagePtrOrig );
  843.     
  844.     if( tErr != noErr )
  845.     {
  846.         DebugStr("\pRequest::FixAEManagerBugPart2 Error AEDisposeDesc gTheApplication->fMessagePtrOrig.");
  847.     }    
  848.  
  849.         //————    Delete the original reply AppleEvent Record
  850.     tErr =  AEDisposeDesc( fReplyPtrOrig );
  851.     
  852.     if( tErr != noErr )
  853.     {
  854.         DebugStr("\pRequest::FixAEManagerBugPart2 Error AEDisposeDesc gTheApplication->fReplyPtrOrig.");
  855.     }    
  856.  
  857. }
  858.  
  859.